# query methods go here
from __future__ import absolute_import
from pkgr.repository.package import RepoPackage
from pkgr.package import Requires
import logging
import sqlite3
from pkgr.database import Database
logger = logging.getLogger('pkgr.repository.database')

class RepositoryDatabase(Database):
    """ Represents a package repository database; like one created by createrepo.
    """
    def __init__(self, repo, repomd=None):
        """ repo: original repo object to which this db is associated to. 
            repomd: A repomd object
        """
        self.repo = repo
        self.repomd = repomd
        
    def load_primarydb(self, path):
        """ Loads a sqlite primarydb from path.
        """
        self.dbpackages = sqlite3.connect(path)
        self.dbpackages.row_factory = dict_factory
        db_curs = self.dbpackages.cursor()
        db_curs.execute("SELECT count(*) as count FROM packages")
        count_row = db_curs.fetchone()
        logger.debug('%s primary database at %s has %s packages.', self.repo.get_name(), path, count_row['count'])
        
    def find_packages_providing(self, r):
        """ Find packages providing requirement r.
        
            Args:
                r(:class:`~pkgr.package.Requires`): A requirement to be provided.
                
            Yields:
                A :class:`~pkgr.repository.package.RepoPackage`
                providing *r*.
        """
        assert isinstance(r, Requires), "r must be a Requires"
        
        logger.debug('Find packages providing: %s', r)
        db_curs = self.dbpackages.cursor()
        db_curs.execute("SELECT * FROM provides pr, packages pa WHERE pr.name = ? AND pa.pkgKey = pr.pkgKey;", (r.get_name(),))
        for package in db_curs.fetchall():
            p = RepoPackage(self.repo, self.dbpackages, **package)
            if p.meets_requirement(r):
                yield p
                
        db_curs.execute("SELECT * FROM files fi, packages pa WHERE fi.name = ? AND pa.pkgKey = fi.pkgKey;", (r.get_name(),))
        for package in db_curs.fetchall():
            p = RepoPackage(self.repo, self.dbpackages, **package)
            if p.meets_requirement(r):
                yield p  
     
    def search_package(self, name, **kwargs):
        """ Searches the database for packages matching the specified arguments
            and yields a RepositoryPackage for each.
        
            Args:
                name(str): The packages name
                
            Kwargs:
                version(str): The packages version 
                release(str): The packages release
                epoch(str): The packages epoch
                arch(str): The packages arch
        """
        db_curs = self.dbpackages.cursor()
        
        queryargs = ['name = ?']
        queryvals = [name]
        
        query_kwargs = ['version', 'release', 'epoch', 'arch']
        for arg in query_kwargs:
            if arg not in kwargs or kwargs.get(arg) is None:
                continue
            queryargs.append('%s = ?' % arg)
            queryvals.append(kwargs.get(arg))
        
        qs = "SELECT * FROM packages WHERE %s;" % ' AND '.join(queryargs)
        db_curs.execute(qs, queryvals)
        
        logger.log(5, 'Executing query: %s (%s)', qs, str(queryvals))
        
        for package in db_curs.fetchall():
            p = RepoPackage(self.repo, self.dbpackages, **package)
            yield p
       
    def search_package_name_desc_contains(self, name_desc):
        db_curs = self.dbpackages.cursor()
        db_curs.execute("SELECT * FROM packages WHERE name LIKE ? or summary LIKE ? or description LIKE ?;", (name_desc,name_desc,name_desc))
        
        for package in db_curs.fetchall():
            p = RepoPackage(self.repo, self.dbpackages, **package)
            yield p
        
    def search_package_name_glob(self, name):
        """ Searches for packages with glob name.
        
            Yields:
                :class:`RepoPackage` instances.
        """
        db_curs = self.dbpackages.cursor()
        db_curs.execute("SELECT * FROM packages WHERE name GLOB ?;", (name,))
        
        for package in db_curs.fetchall():
            p = RepoPackage(self.repo, self.dbpackages, **package)
            yield p
        # ['pkgKey', 'name', 'arch', 'version', 'release', 'summary', 'description', 'url']
        #count_row = 
        #self.dbpackages.query()
    
def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

#con = sqlite3.connect(":memory:")
#
#cur = con.cursor()
#cur.execute("select 1 as a")
#print cur.fetchone()["a"]
